//
//  SelectCarViewController.swift
//  Automobile
//
//  Created by erkebulan elzhan on 8/19/20.
//  Copyright © 2020 erkebulan elzhan. All rights reserved.
//

import UIKit

// MARK: - [Create Car] <-- Comments related to creating car modal


final class SelectCarViewController: UIViewController, Alertable {
    
    // MARK: - Outlets

    lazy private var spinner = SpinnerView()
    
    private lazy var skipBtn: UIButton = {
        let btn = UIButton()
        btn.clipsToBounds = true
        btn.layer.cornerRadius = 15
        btn.setTitle("Пропустить", for: .normal)
        btn.backgroundColor = .whiteBlueColor
        btn.setTitleColor(.greyColor, for: .normal)
        btn.titleLabel!.font = UIFont.systemFont(ofSize: 17, weight: .medium)
        return btn
    }()
    
    private lazy var submitBtn: UIButton = {
        let btn = UIButton()
        btn.clipsToBounds = true
        btn.layer.cornerRadius = 15
        btn.setTitle("Выбрать", for: .normal)
        btn.backgroundColor = .blueColor
        btn.setTitleColor(.white, for: .normal)
        btn.titleLabel!.font = UIFont.systemFont(ofSize: 17, weight: .medium)
        btn.isEnabled = false
        btn.alpha = 0.6
        return btn
    }()

    private lazy var carsTable: UITableView = {
        let tableView = UITableView()
        tableView.tableFooterView = UIView()
        tableView.register(CarSelectCell.self, forCellReuseIdentifier: "carCell")
        tableView.delegate = self
        tableView.dataSource = self
        return tableView
    }()
    
    private lazy var infoView: CardView = {
        let infoView = CardView(text: "Выберите авто с гаража для автоматического заполнения основных полей объявлении.", color: CardView.CardType.info)
        return infoView
    }()
    
    private lazy var warnView: CardView = {
        let warnView = CardView(text: "Гос номер не показывается в объявлении.", color: CardView.CardType.warn)
        return warnView
    }()
    
    private lazy var addCarView: UIView = {
        let view = UIView()
        
        let label = UILabel()
        label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
        label.textColor = .blueColor
        label.textAlignment = .left
        label.text = "Добавить авто"
        
        let icon = UIImageView()
        icon.image = UIImage(named: "plus")
        icon.contentMode = .scaleAspectFit

        view.addSubview(label)
        view.addSubview(icon)
        
        label.snp.makeConstraints { (make) in
            make.leading.centerY.equalToSuperview()
        }
        icon.snp.makeConstraints { (make) in
            make.trailing.centerY.equalToSuperview()
            make.width.height.equalTo(22)
        }
        return view
    }()
    
    private lazy var emptyView: EmptyView = {
        let emptyView = EmptyView()
        emptyView.frame = CGRect(x: 0, y: 0, width: carsTable.frame.width, height: 200)
        return emptyView
    }()

    // [Create Car]
    
    private var createCarModal = CreateCarView()
    
    private lazy var overlayView: UIView = {
        let overlayView = UIView()
        overlayView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.65)
        overlayView.isHidden = true
        return overlayView
    }()
    
    // MARK: - Props
    private var isCarSelected: Bool = false {
        didSet {
            if isCarSelected {
                submitBtn.alpha = 1
                submitBtn.isEnabled = true
            } else {
                submitBtn.alpha = 0.6
                submitBtn.isEnabled = false
            }
        }
    }
    
    private lazy var viewModel: SelectCarViewModel = {
        let vm = SelectCarViewModel()
        vm.delegate = self
        vm.viewModelDelegate = self
        return vm
    }()
    
    // MARK: - UI Actions
    
    @objc private func goBack (sender: UIBarButtonItem) {
        self.navigationController?.popViewController(animated: true)
    }

    @objc private func didSelectNewCar (sender: UITapGestureRecognizer) {
        viewModel.saveToGarage = true
        self.showCreateCarModal()
    }
    
    @objc private func onReady (sender: UIButton) {
        viewModel.saveToGarage = true
        viewModel.createdAd.saveToGarage = true
        viewModel.getCarData(id: (viewModel.currentCar?.id!)!)
    }
    
    @objc private func onSkip (sender: UIButton) {
        viewModel.saveToGarage = false
        self.openMarkModel()
    }
    
    // MARK: - Life-Cycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.setUpUI()
        viewModel.loadMyCars()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        self.setUpNavBar()
    }
}


// MARK: - Private Methods

extension SelectCarViewController {
    
    private func selectCarView (indexPath: IndexPath) {
        var output: [CarModel] = []
        
        for (i, car) in viewModel.myCars.enumerated() {
            var _car: CarModel = car
            if (i == indexPath.row) {
                isCarSelected = !car.isSelected
                viewModel.currentCar = car.car
                _car.isSelected = !car.isSelected
            } else {
                _car.isSelected = false
            }
            output.append(_car)
        }
        
        viewModel.myCars = output
        carsTable.reloadData()
    }
    
    private func showCreateCarModal () {
        createCarModal = CreateCarView()
        createCarModal.delegate = self
        createCarModal.parent = self
        createCarModal.isHidden = false
        overlayView.isHidden = false
        
        self.view.addSubview(createCarModal)
        createCarModal.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview()
            make.bottom.equalTo(view.safeAreaLayoutGuide)
            make.height.equalTo(350)
        }
        self.view.bringSubviewToFront(spinner)
    }
    
    private func openMarkModel () {
        let markaVC = MarksViewController()
        let nvc = UINavigationController(rootViewController: markaVC)
        nvc.navigationController?.navigationBar.prefersLargeTitles = true
        nvc.navigationController?.navigationBar.isTranslucent = false
        nvc.navigationController?.navigationBar.backgroundColor = .white
        
        var carData = markaVC.getCarData()
        carData?.saveToGarage = viewModel.saveToGarage
        markaVC.setProps(carData: carData, resultDelegate: self)
        
        nvc.modalPresentationStyle = .fullScreen
        self.present(nvc, animated: true, completion: nil)
    }
    
    private func openOptions () {
        let vc = OptionsViewController()
        vc.callbackVC = self
        self.navigationController?.pushViewController(vc, animated: true)
    }
}


// MARK: - Adding Car Options

extension SelectCarViewController: OptionsViewControllerDelegate {
    func didSelectedOptions(options: [String : Any]?, filterFormat: [String]? = nil) {
        viewModel.createdAd.customOptions = options!
        self.addPhoto()
    }
}


extension SelectCarViewController: ViewModelProtocol, SelectCarViewModelDelegate {
    func updateSpinner(showSpinner: Bool) {
        showSpinner ? spinner.startAnimating() : spinner.stopAnimating()
        view.isUserInteractionEnabled = !showSpinner
    }
    
    func didHappenError(error: RequestError) {
        self.alertError(error: error)
    }
    
    func updatePosts() {
        carsTable.reloadData()
    }
    
    func getCarInfo(car: Car) {
        self.addPhoto()
    }
    
    func createPost(id: Int) {
        let vc = MainViewController()
        let nvc = UINavigationController(rootViewController: vc)
        nvc.modalPresentationStyle = .fullScreen
        vc.setProps(post: viewModel.createdAd, isPreview: true)
        self.navigationController?.present(nvc, animated: true, completion: nil)
    }
    
    func updateCities(cities: [City]?) {}
}


// MARK: - Creating New Car

extension SelectCarViewController: CreateCarProtocol, UITextFieldDelegate {
    
    func didErrorHappen(title: String, message: String) {
        self.showAlert(title, message)
    }
    
    func didCreateCar(car: Car) {
        viewModel.saveToGarage = true
        viewModel.currentCar = car
        self.openMarkModel()
    }
    
    func hideCreateCarView() {
        self.overlayView.isHidden = true
        self.createCarModal.removeFromSuperview()
        self.createCarModal.isHidden = true
    }
    
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
    }
}


// MARK: - Results VC

extension SelectCarViewController: ResultsVCDelegate {
    /// Adding new Car
    /// - Parameters:
    ///   - data: (Marka, Model, Generation, Serie and e.t.c)
    ///   - type: (Включить, Исключить) mode
    func goBack(data: CarFilter, type: MarkaModelMode) {
        if let generation = data.models[0].generation?[0], let serie = generation.series?[0], let modification = serie.modifications?[0] {
            let newCar = Car(id: 0,
                             carNumber: viewModel.currentCar?.carNumber,
                             carName: viewModel.currentCar?.carName,
                             color: data.color,
                             marka: data.marka,
                             model: data.models[0],
                             generation: generation,
                             carType: viewModel.currentCar?.carType,
                             serie: serie,
                             modification: modification,
                             mileage: data.probeg)
            self.viewModel.addNewCar(car: newCar)
        }
    }
}


// MARK: - Create Ad Delegate

extension SelectCarViewController: AdCreatorProtocol {
    
    func removeEverything() {
        viewModel.createdAd = Post()
    }
    
    func showAdPreview() {
        viewModel.createdAd.saveToGarage = viewModel.saveToGarage
        viewModel.sendAd(ad: viewModel.createdAd)
    }
    
    func getPrice(price: Int?, isObmen: Bool, isRastomozhen: Bool) {
        viewModel.createdAd.price = price!
        viewModel.createdAd.isObmen = isObmen
        viewModel.createdAd.isRastomozhen = isRastomozhen
    }
    
    func getDescriptions(text: String?, onlyAutoNomad: Bool) {
        viewModel.createdAd.description = text != nil && text!.isEmpty ? nil : text
    }

    func getPhoneNumber(number: NumberViewModel.Number?, onlyChat: Bool, noReseller: Bool, isProtected: Bool) {
        if let _number = number {
            viewModel.createdAd.contactNumbers = [_number]
        } else {
            viewModel.createdAd.contactNumbers = []
        }
    }
    
    func getContacts(name: String?, email: String?, city: City?) {
        viewModel.createdAd.contactName = name
        viewModel.createdAd.contactEmail = email
        viewModel.createdAd.city = city
    }
    
    func getImagesData(images: [UIImage]?) {
        viewModel.createdAd.localImgs = images
        viewModel.createdAd.car = viewModel.currentCar!
    }
    
    func giveStateNumber () -> String {
        return viewModel.createdAd.car.carNumber?.fullNumber ?? ""
    }
}


// MARK: - UITable View Delegates


extension SelectCarViewController: UITableViewDelegate, UITableViewDataSource, CarSelectProtocol {
    
    func didSelectCar(indexPath: IndexPath) {
        self.selectCarView(indexPath: indexPath)
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.selectCarView(indexPath: indexPath)
    }
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return viewModel.myCars.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "carCell") as! CarSelectCell
        cell.carModel = viewModel.myCars[indexPath.row]
        cell.delegate = self
        cell.indexPath = indexPath
        
        cell.selectionStyle = .none
        return cell
    }
    
    func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
        let contextItem = UIContextualAction(style: .destructive, title: "Удалить") {  (contextualAction, view, boolValue) in
            self.viewModel.removeCar(car: self.viewModel.myCars[indexPath.row].car)
        }
        
        let swipeActions = UISwipeActionsConfiguration(actions: [contextItem])
        return swipeActions
    }
    
    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        let _view = UIView()
        _view.addSubview(addCarView)
        addCarView.snp.makeConstraints { (make) in
            make.edges.equalToSuperview()
        }
        
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didSelectNewCar(sender:)))
        addCarView.addGestureRecognizer(tapGesture)
        return _view
    }
    
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return "Выберите авто"
    }
    
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let titleLbl = UILabel()
        titleLbl.font = UIFont.systemFont(ofSize: 15, weight: .regular)
        titleLbl.textColor = .greyColor
        titleLbl.sizeToFit()
        titleLbl.text = "Выберите авто"
        
        return titleLbl
    }
    
    func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
        return 60.0
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 60.0
    }
}


// MARK: - UI

extension SelectCarViewController {
    
    private func setUpUI () {
        view.backgroundColor = .white
        self.view.addSubview(infoView)
        self.view.addSubview(warnView)
        self.view.addSubview(carsTable)
        self.view.addSubview(submitBtn)
        self.view.addSubview(skipBtn)
        self.view.addSubview(spinner)
        self.view.addSubview(overlayView)
        
        submitBtn.addTarget(self, action: #selector(onReady(sender:)), for: .touchUpInside)
        skipBtn.addTarget(self, action: #selector(onSkip(sender:)), for: .touchUpInside)
        
        self.addConstraints()
    }
    
    private func addConstraints () {
        infoView.snp.makeConstraints { (make) in
            make.top.equalTo(view.safeAreaLayoutGuide).inset(30)
            make.leading.trailing.equalToSuperview().inset(16)
        }
        warnView.snp.makeConstraints { (make) in
            make.top.equalTo(infoView.snp.bottom).offset(8)
            make.leading.trailing.equalToSuperview().inset(16)
        }
        submitBtn.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.bottom.equalTo(view.safeAreaLayoutGuide).offset(-16)
            make.height.equalTo(44)
        }
        skipBtn.snp.makeConstraints { (make) in
            make.leading.trailing.equalToSuperview().inset(16)
            make.height.equalTo(44)
            make.bottom.equalTo(submitBtn.snp.top).offset(-8)
        }
        carsTable.snp.makeConstraints { (make) in
            make.top.equalTo(warnView.snp.bottom).offset(24)
            make.leading.trailing.equalToSuperview().inset(16)
            make.bottom.equalTo(submitBtn.snp.top).offset(-12)
        }
        spinner.snp.makeConstraints { (make) in
            make.center.equalToSuperview()
        }
        overlayView.snp.makeConstraints { (make) in
            make.top.equalTo(view.safeAreaLayoutGuide)
            make.leading.bottom.trailing.equalToSuperview()
        }
    }
    
    private func setUpNavBar () {
        let backIcon = UIImage(named: "cancel")
        let backButton = UIBarButtonItem(image: backIcon, landscapeImagePhone: backIcon, style: .plain, target: self, action: #selector(goBack(sender:)))
        backButton.tintColor = .greyColor
        
        self.navigationItem.simpleNavBar(title: "Автозаполнение данных", backButton: backButton)
        navigationItem.largeTitleDisplayMode = .always
        navigationController?.navigationBar.largeTitleTextAttributes = [
            NSAttributedString.Key.font: UIFont.systemFont(ofSize: 24, weight: .bold)
        ]
        
        navigationItem.hidesSearchBarWhenScrolling = false
        self.navigationItem.largeTitleDisplayMode = .always
        self.navigationController?.navigationBar.isHidden = false
        self.navigationController?.navigationBar.prefersLargeTitles = true
    }

    private func addPhoto () {
        let vc = ImageSelectVC()
        vc.delegate = self
        let nvc = UINavigationController(rootViewController: vc)
        nvc.modalPresentationStyle = .fullScreen
        nvc.navigationBar.prefersLargeTitles = true
        self.navigationController?.present(nvc, animated: true, completion: nil)
    }
}
